﻿using System;
using System.Collections.Generic;
using Test30.Core;
using Test30.Util;

namespace Test30.Engine
{
    public abstract class BallAction : EnumerableAction
    {
        protected BallAction(NotNull<Entity> entity, Vec center, int radius)
            : base(entity)
        {
            if (radius < 0) throw new ArgumentOutOfRangeException($"radius", "The radius must not be negative.");

            _center = center;
            _radius = radius;
        }

        protected override IEnumerable<ActionResult> OnProcessEnumerable()
        {
            for (int radius = 0; radius <= _radius; radius++)
            {
                Circle circle = new Circle(_center, radius);

                foreach (Vec pos in circle)
                {
                    // only on open tiles
                    if (Dungeon.Bounds.Contains(pos) && IsTileAllowed(pos))
                    {
                        Direction direction = Direction.Towards(pos - _center);

                        OnEffect(pos, direction, circle.IsEdge(pos));
                    }
                }

                yield return ActionResult.NotDone;
            }
        }

        protected virtual bool IsTileAllowed(Vec pos)
        {
            return Dungeon.Tiles[pos].IsTransparent;
        }

        protected abstract void OnEffect(Vec pos, Direction direction, bool leadingEdge);

        private readonly Vec _center;
        private readonly int _radius;
    }
}
